<template>
  <ProTable
    ref="tableRef"
    :fetchListApi="_getDayRunRate"
    :columns="columns"
    :onValuesChange="onChange"
    :onFromReset="onFromReset"
    searchText="统计"
  >
    <template #toolbars>
      <div class="w-full flex justify-between mr-4">
        <Space :size="20">
          <div
            :class="['report_item', { active: currentValue == null }]"
            @click="onSearch(null)"
          >
            <div>
              <span>{{ queryType == 1 ? '全部设备' : '查询范围' }}</span>
            </div>
            <div>
              <span>{{ queryType == '1' ? '设备数' : '天数' }}</span>
              <span class="num" v-if="queryType == '1'">{{
                deviceCount['0'] || 0
              }}</span>
              <span v-else>{{ daysBetween || 0 }}</span>
            </div>
          </div>
          <div
            :class="['report_item', { active: currentValue == 1 }]"
            @click="onSearch(1)"
          >
            <div>
              <span>运行率</span>
              <span>95%以上</span>
            </div>
            <div>
              <span>{{ queryType == '1' ? '设备数' : '天数' }}</span>
              <span class="num">{{ deviceCount[1] || 0 }}</span>
            </div>
          </div>
          <div
            :class="['report_item', { active: currentValue == 2 }]"
            @click="onSearch(2)"
          >
            <div>
              <span>运行率</span>
              <span>95%~90%</span>
            </div>
            <div>
              <span>{{ queryType == '1' ? '设备数' : '天数' }}</span>
              <span class="num">{{ deviceCount[2] || 0 }}</span>
            </div>
          </div>
          <div
            :class="['report_item', { active: currentValue == 3 }]"
            @click="onSearch(3)"
          >
            <div>
              <span>运行率</span>
              <span>90%以下</span>
            </div>
            <div>
              <span>{{ queryType == '1' ? '设备数' : '天数' }}</span>
              <span class="num">{{ deviceCount[3] || 0 }}</span>
            </div>
          </div>
          <div
            :class="['report_item', { active: currentValue == 4 }]"
            @click="onSearch(4)"
          >
            <div>
              <span>服务平均延时(s)</span>
              <span>3秒以上</span>
            </div>
            <div>
              <span>{{ queryType == '1' ? '设备数' : '天数' }}</span>
              <span class="num">{{ deviceCount[4] || 0 }}</span>
            </div>
          </div>
          <div
            :class="['report_item', { active: currentValue == 5 }]"
            @click="onSearch(5)"
          >
            <div>
              <span>异常重启数</span>
              <span>3次以上</span>
            </div>
            <div>
              <span>{{ queryType == '1' ? '设备数' : '天数' }}</span>
              <span class="num">{{ deviceCount[5] || 0 }}</span>
            </div>
          </div>
        </Space>
        <Space>
          <b-button
            icon="export"
            @click="onExport(true)"
            code="detailReport:export"
            >导出</b-button
          >
          <!-- <b-button type="link" icon="export" @click="onExport(false)"
            >导出列表</b-button
          > -->
        </Space>
      </div>
    </template>
  </ProTable>
</template>

<script lang="tsx" setup>
import { computed, ref, watch } from 'vue';
import {
  Descriptions,
  DescriptionsItem,
  RangePicker,
  Space,
} from 'ant-design-vue';
import dayjs from 'dayjs';
import isoWeek from 'dayjs/plugin/isoWeek';
import { saveAs } from 'file-saver';
import { omit } from 'lodash-es';
import * as XLSX from 'xlsx';
import { ProFormProps } from '@/components/ProForm';
import { ProTable, ProTableProps } from '@/components/ProTable/index';
import { useFormModal } from '@/hooks/formModal';
import { isEmptyObject, listToEnum } from '@/utils/utils';
import { getModelInfoById } from '@/api/push';
import { exportMonthList, getDayRunRate } from '@/api/statistics';
import CustomPiker from '../components/customPiker.vue';
import CustomRange from '../components/customRange.vue';
import CustomTree from '../components/customTree.vue';
import { reportStore } from '../store';

dayjs.extend(isoWeek);
const {
  refreshStore,
  deviceModeOptions,
  deviceModeEnum,
  getModelOptions,
  getModelEnum,
  projectList,
  projectEnum,
} = reportStore();

const init = () => {
  refreshStore.timeDelay();
};

init();
const recordParams = ref({});
const deviceCount = ref({});
const daysBetween = ref(7);
const modListEnum = ref<Record<string, any>>({});
const onChange = async (params: any, formState: any) => {
  if (params.hasOwnProperty('queryType')) {
    queryType.value = params['queryType'];
    tableRef.value.search();
  }
  if (params.hasOwnProperty('time')) {
    const start = dayjs(params.time[0]);
    const end = dayjs(params.time[1]);
    daysBetween.value = end.diff(start, 'day');
  }
  if (params.hasOwnProperty('deviceType')) {
    formState.modelId = undefined;
    if (params.deviceType) {
      const res = await getModelInfoById({
        type: params.deviceType,
        modelIds: '',
      });
      modListEnum.value = listToEnum(res.data, 'modelId', 'model');
    } else {
      modListEnum.value = {};
    }
  }
};
const nowData = ref([]);
let res: any;
const _getDayRunRate = async (queryParams: any) => {
  if (queryParams.hasOwnProperty('time') && queryType.value == '2') {
    queryParams['startTime'] = queryParams.time[0];
    queryParams['endTime'] = queryParams.time[1];
  }
  if (queryType.value == '2') {
    delete queryParams.dayList;
  }
  if (queryParams.deviceCode) {
    queryParams.deviceCode = queryParams.deviceCode.replace(/\s+/g, '');
  }
  if (queryType.value == '2' && !queryParams.deviceCode) {
    res = {
      data: {
        countMap: {},
        list: [],
      },
    };
  } else {
    queryParams.runRate = currentValue.value;

    recordParams.value = queryParams;

    res = await getDayRunRate(queryParams);
    if (res.code !== 200) return;
  }
  const { countMap, list } = res.data;
  deviceCount.value = countMap || {};
  const newList = getRows(list || []);

  const { pageNum, pageSize } = queryParams;
  const startIndex = (pageNum - 1) * pageSize;
  const endIndex = startIndex + pageSize;
  const rows = newList.slice(startIndex, endIndex);
  nowData.value = rows;

  return {
    rows,
    total: newList.length,
  };
};
const tableRef = ref();
const currentValue = ref(null);
const onSearch = (runRate: any) => {
  if (currentValue.value === runRate) {
    tableRef.value.search({ runRate: null });
    currentValue.value = null;
    return;
  }
  tableRef.value.search({ runRate });
  currentValue.value = runRate;
};

const queryType = ref('1');
const columns = computed<ProTableProps['columns']>(() => [
  {
    title: '查询类型',
    dataIndex: 'queryType',
    hideInTable: true,
    defaultValue: '1',
    valueEnum: {
      '1': '项目',
      '2': '设备',
    },
  },
  {
    title: '运行日期',
    dataIndex: 'date',
    hideInTable: queryType.value == '1',
    hideInSearch: true,
  },
  {
    title: '运行日期',
    dataIndex: 'dayList',
    hideInTable: true,
    hideInSearch: queryType.value == '2',
    defaultValue: getPreviousSevenDays(),
    customSearchRender(formState) {
      const onChangeForTree = (value: any) => {
        formState['dayList'] = value;
      };
      return (
        <CustomPiker
          formState={formState}
          allowClear={false}
          picker={'date'}
          defaultValue={getPreviousSevenDays()}
          onChange={onChangeForTree}
        ></CustomPiker>
      );
    },
  },
  {
    title: '运行日期',
    dataIndex: 'time',
    hideInTable: true,
    hideInSearch: queryType.value == '1',
    defaultValue: getRangeCurrent(),
    customSearchRender(formState) {
      const onChangeForTree = (value: any) => {
        formState['time'] = value;
      };
      return (
        <CustomRange
          formState={formState}
          allowClear={false}
          picker={'date'}
          defaultValue={getRangeCurrent()}
          onChange={onChangeForTree}
        ></CustomRange>
      );
    },
  },
  {
    title: '设备序列号',
    dataIndex: 'deviceCode',
    hideInSearch: queryType.value == '1',
    hideInTable: true,
  },
  {
    title: '设备序列号',
    dataIndex: 'code',
    hideInSearch: true,
    hideInTable: queryType.value == '2',
  },
  {
    title: '项目名称',
    dataIndex: 'projectId',
    sorter: (a, b) => asciiSort(a.projectId, b.projectId),
    hideInSearch: true,
    valueEnum: {
      ...projectEnum.value,
    },
  },
  {
    title: '项目名称',
    dataIndex: 'projectId',
    hideInTable: true,
    hideInSearch: queryType.value == '2',
    customSearchRender(formState) {
      const onChangeForTree = (value: any) => {
        formState['projectId'] = value;
      };
      return (
        <CustomTree
          formState={formState}
          data={projectList.value}
          onChange={onChangeForTree}
        ></CustomTree>
      );
    },
  },
  {
    title: '设备类型',
    dataIndex: 'deviceType',
    hideInSearch: queryType.value == '2',
    valueEnum: {
      ...deviceModeEnum.value,
    },
    width: 150,
    sorter: (a, b) => asciiSort(a.deviceType, b.deviceType),
  },
  {
    title: '设备型号',
    dataIndex: 'modelId',
    hideInSearch: queryType.value == '2',
    hideInTable: true,
    valueEnum: isEmptyObject(modListEnum.value)
      ? {
          ...getModelEnum.value,
        }
      : { ...modListEnum.value },
  },
  {
    title: '设备型号',
    dataIndex: 'deviceModel',
    width: 150,
    hideInSearch: true,
    sorter: (a, b) => asciiSort(a.deviceModel, b.deviceModel),
    // valueEnum: {
    //   ...getModelEnum.value,
    // },
  },
  {
    title: '安装单位',
    dataIndex: 'address',
    hideInSearch: true,
  },
  {
    title: '实际签到数/应签到数',
    dataIndex: 'should',
    hideInSearch: true,
  },
  {
    title: '运行率',
    dataIndex: 'runRate',
    hideInSearch: true,
  },
  {
    title: '运行时长',
    dataIndex: 'runDuration',
    hideInSearch: true,
  },
  {
    title: '管理状态上报时间',
    dataIndex: 'reportTime',
    hideInSearch: true,
  },
  {
    title: '服务平均延时(s)',
    dataIndex: 'timeDelay',
    hideInSearch: true,
  },
  {
    title: '异常重启数',
    dataIndex: 'exceptionRestartSum',
    hideInSearch: true,
  },
]);

const getPreviousSevenDays = () => {
  const today = dayjs();
  const endTime = today.format('YYYY-MM-DD');
  return endTime;
};

const getRangeCurrent = () => {
  const today = dayjs();
  const endTime = today.format('YYYY-MM-DD');
  const start = today.subtract(7, 'day');
  const startTime = start.format('YYYY-MM-DD');
  return [startTime, endTime];
};
const onFromReset = (params: any) => {
  currentValue.value = null;
  tableRef.value.search();
};
// 导出
const onExport = async (all: any) => {
  if (all) {
    await exportMonthList(recordParams.value);
  } else {
    const arr = ['queryType', 'dayList', 'time', 'modelId'];
    const _columns = columns.value
      .filter((item: any) => !arr.includes(item.dataIndex))
      .filter((i) => !i.hideInTable);
    const tableData = transData(_columns, nowData.value);
    const ws = XLSX.utils.aoa_to_sheet(tableData);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
    XLSX.writeFile(wb, '运行率_明细报表.xlsx');
  }
};

// 处理数据
const transData = (columns: any, tableList: any) => {
  const obj = columns.reduce((acc: any, cur: any) => {
    if (!acc.titles && !acc.keys) {
      acc.titles = [];
      acc.keys = [];
    }
    acc.titles.push(cur.title);
    acc.keys.push(cur.dataIndex);
    return acc;
  }, {});
  const tableBody = tableList.map((item: any) => {
    return obj.keys.map((key: any) => {
      if (key === 'deviceType') {
        return deviceModeEnum.value[item[key]];
      }
      if (key === 'projectId') {
        return projectEnum.value[item[key]];
      }
      return item[key];
    });
  });
  return [obj.titles, ...tableBody];
};

const getRows = (data: any) => {
  const getRow = (row: any) => {
    const result: any = [];

    row.runRateVOList?.forEach((item: any) => {
      const newObj = {
        ...item,
        ...omit(row, ['runRateVOList']),
      };

      result.push(newObj);
    });

    return result;
  };

  const newArray: any = [];
  data.forEach((item: any) => {
    newArray.push(...getRow(item));
  });
  return newArray;
};

const asciiSort = (item1: any, item2: any) => {
  const str1 = item1 ? item1.toString() : ' ';
  const str2 = item2 ? item2.toString() : ' ';
  if (str1.length !== str2.length) {
    return str1.length - str2.length;
  }
  for (let i = 0; i < str1.length; i++) {
    const code1 = str1.charCodeAt(i);
    const code2 = str2.charCodeAt(i);
    if (code1 !== code2) {
      return code1 - code2;
    }
  }
  return 0;
};

const findLabelById = (tree: any, targetId: any) => {
  console.log(tree, targetId, 'id');

  const searchNode = (node: any) => {
    if (node.id === targetId) {
      return node.label;
    }

    if (node.children && node.children.length > 0) {
      for (let child of node.children) {
        let result: any = searchNode(child);
        if (result !== undefined) {
          return result;
        }
      }
    }
    return undefined;
  };

  return searchNode(targetId);
};
</script>

<style lang="scss" scoped>
.item {
  cursor: pointer;
  height: 80px;
  width: 200px;
  border-radius: 10px;
  background-color: rgba(0, 0, 0, 0.2);
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  padding: 0 20px 15px;
  & > div {
    display: flex;
    flex-direction: column;
    span {
      &:nth-child(2) {
        font-size: 16px;
      }
    }
  }
  .num {
    font-size: 20px;
  }
  &.active {
    background-color: rgba(0, 0, 0, 0.5);
  }
}
</style>
